<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>canvas跟随鼠标的丝带效果</title>
	<style>
		*{margin: 0;padding: 0;}
		html,body{height: 100%;}
		body{background: #131313;}
		canvas{position: absolute;top: 50%;left:50%;transform: translate(-50%,-50%);border: 10px solid #333;}
	</style>
</head>
<body>

<canvas id="canvas"></canvas>


<script>
	var canvas,context;
	var WIDTH = Math.min(800,document.body.offsetWidth);
	var HEIGHT = Math.min(600,document.body.offsetHeight);
	var NUM = 25;
	var lines = [];
	var RADIUS = 110;
	var RADIUS_SCALE = 1;
	var RADIUS_SCALE_MIN = 1;
	var RADIUS_SCALE_MAX = 1.5;

	var MouseX = window.innerWidth - WIDTH;
	var MouseY = window.innerHeight - HEIGHT;
	var mouseIsDown = false;

	
	window.onload = function(){
		canvas = document.getElementById('canvas');
		canvas.width = WIDTH;
		canvas.height = HEIGHT;

		context = canvas.getContext("2d");

		document.addEventListener('mousemove',documentMousemove,false);
		document.addEventListener('mousedown',documentMousedown,false);
		document.addEventListener('mouseup',documentMouseup,false);
		canvas.addEventListener('touchstar',canvasTouchStar,false);
		canvas.addEventListener('touchmove',canvasTouchMove,false);
		window.addEventListener('resize',resize,false);

		addLines();
		setInterval(function(){
			render()
		},16)
	}

	function render(){
		if(mouseIsDown){
			RADIUS_SCALE += (RADIUS_SCALE_MAX - RADIUS_SCALE)*0.02;
		}else{
			RADIUS_SCALE -= (RADIUS_SCALE - RADIUS_SCALE_MIN) * 0.02;
		}
		RADIUS_SCALE = Math.min(RADIUS_SCALE,RADIUS_SCALE_MAX);


		context.fillStyle = 'rgba(0,0,0,0.05)';
		context.fillRect(0,0,WIDTH,HEIGHT);
		for(var i = 0 ; i < NUM ; i++){
			var line = lines[i];
			var lp = { x:line.position.x , y:line.position.y};

			line.angle += line.speed;

			line.shift.x += (MouseX - line.shift.x)*line.speed;
			line.shift.y += (MouseY - line.shift.y)*line.speed;

			line.position.x = line.shift.x + Math.cos(i + line.angle) * (line.orbit*RADIUS_SCALE);
			line.position.y = line.shift.y + Math.sin(i + line.angle) * (line.orbit*RADIUS_SCALE);

			line.position.x = Math.max( Math.min( line.position.x, WIDTH ), 0 );
			line.position.y = Math.max( Math.min( line.position.y, HEIGHT ), 0 );

			line.size += ( line.targetSize - line.size ) * 0.05;

			if( Math.round( line.size ) == Math.round( line.targetSize ) ) {
				line.targetSize = 1 + Math.random() * 7;
			}

			context.beginPath();
			context.fillStyle = line.fillColor;
			context.strokeStyle = line.fillColor;
			context.lineWidth = line.size;
			context.moveTo(lp.x,lp.y);
			context.lineTo(line.position.x , line.position.y);
			context.stroke();
			context.arc(line.position.x , line.position.y , line.size/2 , 0, Math.PI*2,true);
			context.fill();

		}
	}

	function addLines(){
		for (var i = 0; i < NUM ; i++) {
			var aLine = {
				position:{x:MouseX,y:MouseY},
				shift:{x:MouseX,y:MouseY},
				size:1,
				angle:0,
				speed:0.01 + Math.random()*0.04,
				targetSize:1,
				fillColor:'#' + (Math.random() * 0x404040 + 0xaaaaaa | 0).toString(16),
				orbit:RADIUS*0.5 + Math.random()*0.5*RADIUS
			}
			lines.push(aLine);
		}
	}

	function documentMousemove(event){
		MouseX = event.clientX - (window.innerWidth - WIDTH)/2;
		MouseY = event.clientY - (window.innerHeight - HEIGHT)/2;
	}
	function documentMousedown(){
		mouseIsDown = true;
	}
	function documentMouseup(){
		mouseIsDown = false;
	}
	function canvasTouchStar(event) {
		if(event.touches.length == 1) {
			event.preventDefault();

			MouseX = event.touches[0].pageX - (window.innerWidth - WIDTH) * .5;
			MouseY = event.touches[0].pageY - (window.innerHeight - HEIGHT) * .5;
		}
	}
	
	function canvasTouchMove(event) {
		if(event.touches.length == 1) {
			event.preventDefault();

			MouseX = event.touches[0].pageX - (window.innerWidth - WIDTH) * .5;
			MouseY = event.touches[0].pageY - (window.innerHeight - HEIGHT) * .5;
		}
	}
	
	function resize() {
		WIDTH = Math.min(800,document.body.offsetWidth);
		HEIGHT = Math.min(600,document.body.offsetHeight);
		
		canvas.width = WIDTH;
		canvas.height = HEIGHT;
	}
</script>
	
</body>
</html>